import {Vue} from "../../../../source/vue/types/vue";

export interface IOffset{
  offsetTop:number
}

export interface IList {
  el:any,
  // 带单位的y坐标
  top: number
  // 带单位的x坐标
  left: number
  // 带单位的宽度
  width: number
  // 带单位的高度
  height: number
  // 坐标是否被计算过
  isPosition: boolean
  // 唯一标识符,用于避免重复压入lists
  id:number
}

export class WaterFall {
  // 瀑布流元素数组
  _lists: IList[];
  // 包裹_lists的容器宽度
  _container: Vue;
  // 行数
  _column: number;
  // 元素左边距
  _left: number;
  // 每个元素的宽度
  _elWidth: number;

  /**
   * 提供列数与元素宽度,让代码自动计算边距
   * @param {Vue} container 容器对象
   * @param {number} elWidth 单个元素的宽度
   * @param {object} lists 要排列的元素的对象
   * @param {number} column 要摆放的列数
   */
  constructor(container, elWidth, lists, column){
    this._lists = lists;
    this._container = container;
    this._elWidth = elWidth;
    this._column = column===undefined?WaterFall.computedColumn(this._container, this._elWidth):column;
  }

  /**
   * @return {IList[]} value
   */
  get lists():IList[] {
    return this._lists;
  }

  /**
   * @param {IList[]} value
   */
  set lists(value: IList[]) {
    this._lists = value;
  }

  /**
   * 将id不重复的对象压入_lists中,并初始化isPosition的值
   * @param {IList[]} value
   */
  add(value: IList[]) {
    for(let i=0,length=value.length;i<length;i++){
      value[i].isPosition=false;
      if(this._lists[i].id !== value[i].id)this._lists.push(value[i]);
    }
  }

  /**
   * 移除指定区间的元素
   * @param {number} begin
   * @param {number} end
   */
  remove(begin:number, end:number){
    const _end = end>this._lists.length?this._lists.length-1:end;
    this._lists.splice(begin,_end);
  }

  /**
   * 计算填充剩余空间所需要的缩放大小
   * @param {HTMLElement} el 瀑布流容器
   * @param {number} elWidth 单个元素的宽度
   * @param {number} column 要摆放的列数
   * @return {number} result
   */
  static widthFill(el:HTMLElement, elWidth:number, column:number):number{
    let _column = column-1;
    const surplusWidth:number = (el.clientWidth - elWidth) - (_column * elWidth);
    return (surplusWidth/_column);
  }
  /**
   * 计算列数
   */
  static computedColumn(container, elWidth){
    return Math.floor((container.$el.clientWidth/elWidth))
  }

  // top偏移量
  offsetTop:number;

  setOffset(offset:IOffset){
    offset=offset===undefined?{offsetTop:0}:offset;
    let {offsetTop} = offset;
    this.offsetTop = offsetTop;
  }

  /**
   * 计算各个元素的位置
   * @param {IList}value 需要排序的元素列表
   * @param {IOffset}offset 元素边距
   * @return {IList[]} value 以计算的元素
   */
  position(value = this._lists, offset?:IOffset){
    this._left = WaterFall.widthFill(this._container.$el, this._elWidth, this._column);
    this.setOffset(offset);
    const column = this._column;
    this.add(value);
    if(!value[0].isPosition){
      value[0].top = value[0].left = 0;
      value[0].width = this._elWidth;
      value[0].isPosition = true;
    }
    for(let i=1,length=value.length;i<length;i++){
     if(i<column&&!value[i].isPosition){
       value[i].top = 0;
       value[i].left = this._elWidth*(i%column)+this._left*(i%column);
       value[i].width = this._elWidth;
       value[i].isPosition = true;
     }else if(!value[i].isPosition){
       value[i].top = (value[i-column].top+value[i-column].el.clientHeight)+this.offsetTop;
       value[i].left = this._elWidth*(i%column)+this._left*(i%column);
       value[i].width = this._elWidth;
       value[i].isPosition = true;
     }
    }
    return value;
  }
}

